package com.yfbao.horizon.docker.trx;


import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * TODO：定时重试补偿执行任务的job
 * 全局唯一执行
 * //todo: 后台任务执行线程：
 * 2、定期执行历史执行失败任务，执行5分钟前（updateTime）执行失败的任务，
 */
@Slf4j
@Component
public class TrxTaskRepairJob   {

//    @Autowired
//    private CtpUserDTPServcie ctpUserDTPServcie;
//    @Autowired
//    private DistributedLockFactory lockFactory;
//
//    @Autowired
//    private TrxTaskDao trxTaskDao;
//
//    @Autowired
//    private FailTrxTaskDao failTrxTaskDao;
//
//
//    @Override
//    public SingleResponse<?> exec() {
//        try {
//            doTrxTaskRepair();
//        }catch (Throwable t){
//            log.error("doTrxTaskRepair error",t);
//        }
//        return null;
//    }
//
//
//    public void doTrxTaskRepair(){
//        DateTime dateTime = DateUtil.offsetMinute(new Date(), (-1) * UserTrxConstants.TASK_RETRY_BEFORE_MINUTE);
//        Wrapper wrapper = new Wrapper(TrxTask.class);
//        wrapper.and().andLessThan("updateTime",dateTime);
//        List<TrxTask> trxTasks = trxTaskDao.selectListByWrapperIgnoreTenant(wrapper);
//        if(trxTasks == null || trxTasks.isEmpty()){
//            return ;
//        }
//        for (TrxTask trxTask : trxTasks) {
//            Long trxId = trxTask.getTrxId();
//            Apps.getRequestContext().setTenantId(trxTask.getTenantId());
//            TrxHistory trxHistory = ctpUserDTPServcie.getTrxHistory(trxId, UserTrxConstants.COMMIT, true);
//            if(trxHistory != null){
//                ctpUserDTPServcie.updateTrxTaskSuccess(trxId);
//                continue;
//            }
//            Integer retryTime = trxTask.getRetryTime();
//            if(retryTime >UserTrxConstants.MAX_TASK_RETRY ){
//                long createTime = trxTask.getCreateTime().getTime();
//                long threeDaybefore = DateUtil.offsetDay(new Date(), -3).getTime();
//                if(createTime<threeDaybefore){
//                    //最大重试时间后如何处理，转储至最终失败任务表
//                    addFailTask(trxTask);
//                    continue;
//                }
//                //超过重试上限后，每隔1小时重试一次
//                long updateTime = trxTask.getUpdateTime().getTime();
//                long time = DateUtil.offsetHour(new Date(), -1).getTime();
//                if(updateTime>time){
//                    //最近1小时以内执行过，本次不在执行
//                    continue;
//                }
//            }
//            runTrxTask(trxTask);
//        }
//    }
//
//    @Transactional
//    public void runTrxTask(TrxTask trxTask){
//        Apps.getRequestContext().setTenantId(trxTask.getTenantId());
//        Long trxId = trxTask.getTrxId();
//        boolean locked = false;
//        String key = CacheUtils.getCompleteCacheKey("retryTrx", String.valueOf(trxId));
//        Lock lock = lockFactory.newLock(key,10*1000L);
//        try {
//            locked = lock.tryLock(1, TimeUnit.SECONDS);
//            log.info("get trx lock:" + key+","+locked);
//            if(locked){
//                if(trxTask.getTaskStatus().equals(UserTrxConstants.TASK_FINISHED)){
//                    ctpUserDTPServcie.updateTrxTaskSuccess(trxId);
//                    return;
//                }
//                if(!trxTask.getTaskStatus().equals(UserTrxConstants.TASK_RUNNING)){
//                    trxTask.setTaskStatus(UserTrxConstants.TASK_RUNNING);
//                    ctpUserDTPServcie.reliableUpdateTrxTask(trxTask,0);
//                }
//
//                boolean b = TrxTaskUtil.trxInvoke(trxTask);
//                if(b){
//                    //执行完成，放入历史表
//                    ctpUserDTPServcie.updateTrxTaskSuccess(trxId);
//                    return ;
//                }
//            }
//
//            trxTask.setTaskStatus(UserTrxConstants.TASK_FAILED);
//            trxTask.setRetryTime(trxTask.getRetryTime()+1);
//            ctpUserDTPServcie.reliableUpdateTrxTask(trxTask,0);
//        } catch (Throwable e) {
//            log.error("trxTask retry error:"+ trxId,e);
//            ctpUserDTPServcie.updateTrxTaskStatus(trxId,UserTrxConstants.TASK_FAILED);
//        }finally {
//            if(locked){
//                lock.unlock();
//            }
//        }
//    }
//
//    /**
//     * 重试后加入重试表
//     * @param task
//     */
//    public void addFailTask(TrxTask task){
//        FailTrxTask failTrxTask = new FailTrxTask();
//        failTrxTask.setTrxId(task.getTrxId());
//        failTrxTask.setServiceName(task.getServiceName());
//        failTrxTask.setClassName(task.getClassName());
//        failTrxTask.setMethod(task.getMethod());
//        failTrxTask.setParamSize(task.getParamSize());
//        failTrxTask.setParamData(task.getParamData());
//        failTrxTaskDao.create(failTrxTask);
//    }
}
